package foodmaterial.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import foodmaterial.action.RecipeAction;
import foodmaterial.dao.RecipeDao;
import foodmaterial.dto.CustomerRecipePriceTemplateDto;
import foodmaterial.dto.RecipeSupplyDto;
import foodmaterial.dto.RecipeTemplateDto;
import foodmaterial.dto.RecipeTypeDto;
import foodmaterial.entity.*;
import foodmaterial.service.RecipeService;
import foodmaterial.utils.Constants;
import foodmaterial.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

@Service
public class RecipeServiceImpl extends BaseService implements RecipeService {
    @Autowired
    private RecipeDao dao ;

    private String checkRecipeType(RecipeType recipeType) {
        RecipeTypeDto mt = new RecipeTypeDto() ;
        mt.setName(recipeType.getName());
        List<RecipeType> list = dao.selectRecipeType(mt) ;
        return checkExist(list,recipeType) ;
    }

    @Override
    public String addRecipeType(RecipeType recipeType) {
        String result = checkRecipeType(recipeType) ;
        if (result != null) return result ;
        recipeType.setId(nextId());
        int row = dao.insertRecipeType(recipeType);
        if (row <= 0) return "新增菜谱分类失败" ;
        return null ;
    }

    @Override
    public String modifyRecipeType(RecipeType recipeType) {
        String result = checkRecipeType(recipeType) ;
        if (result != null) return result ;
        int row = dao.updateRecipeType(recipeType);
        if (row <= 0) return "没有此菜谱分类信息" ;
        return null ;
    }

    @Override
    public List<RecipeType> queryRecipeType(RecipeTypeDto dto) {
        return dao.selectRecipeType(dto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addRecipeTemplate(RecipeTemplate recipeTemplate) {
        recipeTemplate.setId(nextId());
        for (RecipeTemplateDetails detail: recipeTemplate.getDetails()) {
            detail.setId(nextId());
            detail.setTemplateId(recipeTemplate.getId());
        }
        dao.insertRecipeTemplate(recipeTemplate) ;
        return dao.insertRecipeTemplateDetails(recipeTemplate.getDetails());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int modifyRecipeTemplate(RecipeTemplate recipeTemplate) {
        dao.deleteRecipeTemplateDetails(recipeTemplate.getId()) ;
        for (RecipeTemplateDetails detail: recipeTemplate.getDetails()) {
            detail.setId(nextId());
            detail.setTemplateId(recipeTemplate.getId());
        }
        dao.updateRecipeTemplate(recipeTemplate) ;
        return dao.insertRecipeTemplateDetails(recipeTemplate.getDetails());
    }

    @Override
    public int stopRecipeTemplate(RecipeTemplate menuTemplate) {
        return dao.stopRecipeTemplate(menuTemplate);
    }

    @Override
    public List<RecipeTemplate> queryRecipeTemplate(RecipeTemplateDto dto) {
        return dao.selectRecipeTemplate(dto);
    }

    @Override
    public List<RecipeTemplateDetails> queryRecipeTemplateDetails(Long templateId) {
        return dao.selectRecipeTemplateDetails(templateId);
    }

    @Override
    public RecipeTemplate queryRecipeTemplateById(Long id) {
        RecipeTemplateDto dto = new RecipeTemplateDto() ;
        dto.setId(id);
        List<RecipeTemplate> list = dao.selectRecipeTemplate(dto) ;
        if (list == null || list.isEmpty()) return null;
        list.get(0).setDetails(dao.selectRecipeTemplateDetails(id)) ;
        return list.get(0) ;
    }

    private String checkRecipeSupply(RecipeAction.Supply supply) {
        RecipeSupplyDto where = new RecipeSupplyDto() ;
        where.setBeginSupplyDate(DateUtil.format(supply.getBeginSupplyDate(), Constants.DEFAULT_DATE_FORMAT));
        where.setEndSupplyDate(DateUtil.format(supply.getEndSupplyDate(),Constants.DEFAULT_DATE_FORMAT));
        where.setIds(supply.getRecipeId());
        int total = dao.checkRecipeSupplyCount(where) ;
        if (total == 0) return null ;
        PageHelper.startPage(1,50) ;
        List<RecipeSupply> list = dao.checkRecipeSupply(where) ;
        Map<String,List<Date>> choice = new HashMap<>() ;
        for (RecipeSupply rs : list) {
            if (choice.containsKey(rs.getTemplateName())) {
                choice.get(rs.getTemplateName()).add(rs.getSupplyDate()) ;
            } else {
                List<Date> list1 = new ArrayList<>();
                list1.add(rs.getSupplyDate()) ;
                choice.put(rs.getTemplateName(),list1) ;
            }
        }
        StringBuilder sb = new StringBuilder() ;
        choice.forEach((k,v) -> {
            sb.append(k).append("：在[") ;
            for (Date date : v) {
                sb.append(this.getDate(date)).append(',');
            }
            sb.deleteCharAt(sb.length() - 1) ;
            sb.append("]已经发布；");
        });
        return sb.toString() ;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addRecipeSupply(RecipeAction.Supply supply) {
        String check = checkRecipeSupply(supply) ;
        if (check != null) return check ;
        Date currentDate = DateUtil.parse(this.getCurrentDate()) ;
        if (supply.getBeginSupplyDate().before(currentDate)) {
            return "菜谱供应开始日期要大于等于当前系统日期" ;
        }
        if (supply.getEndSupplyDate().getTime() < supply.getBeginSupplyDate().getTime()) {
            return "菜谱供应截至日期要大于等于开始日期" ;
        }
        List<Date> dateList = DateUtil.dateRange(supply.getBeginSupplyDate(),supply.getEndSupplyDate()) ;

        List<Long> ids = supply.getRecipeId() ;
        List<RecipeSupply> recipeSupplyList = new ArrayList<>();
        for (Long id : ids) {
            for (Date date : dateList) {
                RecipeSupply rs = new RecipeSupply() ;
                rs.setId(nextId());
                rs.setTemplateId(id);
                rs.setSupplyDate(date);
                recipeSupplyList.add(rs) ;
            }
        }
        int result = dao.insertRecipeSupply(recipeSupplyList);
        if (result <= 0) return "新增菜谱供应失败" ;
        return null ;

    }

    @Override
    public String removeRecipeSupply(RecipeSupplyDto dto) {
        if (dto.getBeginSupplyDate() == null && dto.getEndSupplyDate() == null && dto.getId() == null) return "请输入删除的条件" ;
        if ((dto.getBeginSupplyDate() != null && dto.getEndSupplyDate() == null) ||
                (dto.getBeginSupplyDate() == null && dto.getEndSupplyDate() != null)) return "请输入删除的日期范围" ;
        Date end = dto.getEndSupplyDate() != null ? DateUtil.parse(dto.getEndSupplyDate(),Constants.DEFAULT_DATE_FORMAT) : null ;
        Date begin = dto.getBeginSupplyDate() != null ? DateUtil.parse(dto.getBeginSupplyDate(),Constants.DEFAULT_DATE_FORMAT) : null;
        if (end != null && begin != null && end.before(begin)) return "截至日期大于等于开始日期";
        if (dto.getId() != null) {
            dto.setBeginSupplyDate(null);
            dto.setEndSupplyDate(null);
            dto.setTemplateId(null);
        }
        int row =  dao.deleteRecipeSupply(dto);
        if (row <= 0) return "此时间范围没有菜谱发布信息" ;
        return null ;
    }

    @Override
    public List<RecipeSupply> queryRecipeSupply(RecipeSupplyDto dto) {
        return dao.selectRecipeSupply(dto);
    }

    @Override
    public PageInfo<RecipeTemplate> queryRecipe(RecipeTemplateDto dto) {
        PageHelper.startPage(dto.getPageNo(),dto.getPageSize()) ;
        List<RecipeTemplate> result = null ;
        if (StringUtils.isEmpty(dto.getSupplyDate())) {
            if (dto.getVip().booleanValue()) result = dao.selectVipRecipe(dto);
            else result = dao.selectRecipe(dto);
        } else {
            if (dto.getVip().booleanValue()) result = dao.selectVipSupplyRecipe(dto);
            else result = dao.selectSupplyRecipe(dto);
        }
        PageInfo<RecipeTemplate> pageInfo = new PageInfo<>(result) ;
        if (result.isEmpty()) return pageInfo ;
        long templateId = -1;
        int start = 0 ;
        List<RecipeTemplateDetails> details = dao.selectRecipeDetails(result) ;
        for (RecipeTemplate template : result) {
            template.setDetails(new ArrayList<>());
            templateId = template.getId().longValue() ;
            for (int i = start ; i < details.size() ; i++) {
                if (details.get(i).getTemplateId().longValue() != templateId) {
                    start = i ;
                    break;
                }
                template.getDetails().add(details.get(i)) ;
            }
        }
        return pageInfo ;
    }

    @Override
    public String batchModifyRecipePrice(List<RecipeTemplate> recipes) {
        if (recipes == null || recipes.isEmpty()) return "请至少设置一个菜谱价格的修改信息" ;
        BigDecimal bd = new BigDecimal("0.00") ;
        for (RecipeTemplate rt : recipes) {
            if (rt.getId() == null || rt.getPrice() == null || rt.getPrice().compareTo(bd) <= 0) {
                return rt.getName() + "价格不能为空，并大于0" ;
            }
        }
        int result = dao.batchUpdateRecipePrice(recipes);
        if (result <= 0) return "没有菜谱价格的修改信息" ;
        return null ;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addCustomerRecipePriceTemplate(CustomerRecipePriceTemplate customerPriceTemplate) {
        customerPriceTemplate.setId(nextId());
        List<CustomerRecipePriceTemplateDetail> details = customerPriceTemplate.getDetail();
        for (CustomerRecipePriceTemplateDetail detail : details) {
            detail.setId(nextId());
            detail.setTemplateId(customerPriceTemplate.getId());
            detail.setPrice(detail.getVipPrice());
        }
        dao.insertCustomerRecipePriceTemplateDetail(details) ;
        return dao.insertCustomerRecipePriceTemplate(customerPriceTemplate);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int modifyCustomerRecipePriceTemplate(CustomerRecipePriceTemplate customerPriceTemplate) {
        List<CustomerRecipePriceTemplateDetail> details = customerPriceTemplate.getDetail();
        for (CustomerRecipePriceTemplateDetail detail : details) {
            detail.setId(nextId());
            detail.setTemplateId(customerPriceTemplate.getId());
            detail.setPrice(detail.getVipPrice());
        }
        dao.deleteCustomerRecipePriceTemplateDetail(customerPriceTemplate.getId());
        dao.insertCustomerRecipePriceTemplateDetail(details) ;
        return dao.updateCustomerRecipePriceTemplate(customerPriceTemplate) ;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeCustomerRecipePriceTemplate(Long templateId) {
        dao.deleteCustomerRecipePriceTemplate(templateId);
        return dao.deleteCustomerRecipePriceTemplateDetail(templateId);
    }

    @Override
    public List<CustomerRecipePriceTemplate> queryCustomerRecipePriceTemplate(CustomerRecipePriceTemplateDto dto) {
        return dao.selectCustomerRecipePriceTemplate(dto);
    }

    @Override
    public List<CustomerRecipePriceTemplateDetail> queryCustomerRecipePriceTemplateDetail(CustomerRecipePriceTemplateDto dto) {
        return dao.selectCustomerRecipePriceTemplateDetail(dto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addCustomerRecipePrice(RecipeAction.CustomerPriceChoice customerPriceChoice) {
        List<CustomerRecipePrice> list = new ArrayList<>() ;
        for (Long customerId : customerPriceChoice.getCustomerIds()) {
            CustomerRecipePrice cp = new CustomerRecipePrice() ;
            cp.setCustomerId(customerId);
            cp.setTemplateId(customerPriceChoice.getTemplateId());
            list.add(cp) ;
        }
        CustomerRecipePriceTemplateDto dto = new CustomerRecipePriceTemplateDto() ;
        dto.setCustomerIds(customerPriceChoice.getCustomerIds());
        dao.deleteCustomerRecipePrice(dto);
        return dao.insertCustomerRecipePrice(list);
    }

    @Override
    public int removeCustomerRecipePrice(CustomerRecipePriceTemplateDto dto) {
        return dao.deleteCustomerRecipePrice(dto);
    }

    @Override
    public List<CustomerRecipePrice> queryCustomerRecipePrice(CustomerRecipePriceTemplateDto dto) {
        return dao.selectCustomerRecipePrice(dto);
    }

}
